/**
 * <br>项目名: fastdfs-api
 * <br>文件名: UploadCtrl.java
 * <br>Copyright 2015 恒昌互联网运营中心
 */
package com.credithc.fastdfs.api.web;

import com.credithc.fastdfs.api.bean.DownloadReqBean;
import com.credithc.fastdfs.api.config.SystemConfig;
import com.credithc.fastdfs.api.entity.ErrorInfo;
import com.credithc.fastdfs.api.entity.FdfsInfo;
import com.credithc.fastdfs.api.exception.ResourceNotFoundException;
import com.credithc.fastdfs.api.service.ErrorInfoService;
import com.credithc.fastdfs.api.service.FdfsInfoService;
import com.credithc.fastdfs.api.util.CommonUtil;
import com.credithc.fastdfs.api.util.HttpClientProxy;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <br>
 * 类 名: DownloadCtrl <br>
 * 描 述: 描述类完成的主要功能 <br>
 * 作 者: zj <br>
 * 创 建： 2015年5月11日 <br>
 * 版 本：v1.0.0 <br>
 * <br>
 * 历 史: (版本) 作者 时间 注释
 */
@Controller
@RequestMapping("/downloadFile.hc")
public class DownloadCtrl extends BaseController {
	private Logger log = LoggerFactory.getLogger(DownloadCtrl.class);
	@Resource(name = "errorInfoService")
	private ErrorInfoService errorInfoService;

	@Resource(name = "fdfsInfoServiceImpl")
	private FdfsInfoService fdfsInfoServiceImpl;

	/**
	 * <br>描 述： 下传文件
	 * <br>作 者：checkSun
	 * <br>历 史: (版本) 作者 时间 注释
	 * @param request
	 * @param response
	 * @param downloadReqBean
	 */
	@RequestMapping(method = { RequestMethod.GET })
	public void downloadFile(HttpServletRequest request,
			HttpServletResponse response, DownloadReqBean downloadReqBean) {
		String filename = "nofile";

		try {
			/* 上传参数判断 */
			if (null == downloadReqBean) {
				responseForClient(response, "请求参数错误", request, filename);
				return;
			}

			String fsId = downloadReqBean.getFsId();

			if (null == fsId || ("".equals(fsId.trim()))) {
				responseForClient(response, "文件唯一性ID不能为空", request, filename);
				return;
			}
			//支持带扩展名的id
			fsId = StringUtils.substringBefore(fsId, ".");

			String openType = downloadReqBean.getOpenType();

			FdfsInfo finfo = fdfsInfoServiceImpl.selectByPrimaryKey(fsId);

			if (finfo == null) {
				responseForClient(response, "无相关附件记录", request, filename);
				return;
			}
			/* 文件是否有效：0-有效，1-删除，2-物理删除 */
			if (0 != finfo.getFileSaveStatus()) {
				responseForClient(response, "该资源已被移除", request, filename);
				return;
			}
			filename = finfo.getFileName();

			if (null != downloadReqBean.getFileName()
					&& !"".equals(downloadReqBean.getFileName())) {
				filename = downloadReqBean.getFileName();
			}
			/*
			 * 1.采用写入的主文件服务器获取url String url =
			 * FastdfsUtil.getInstance().getFileUrl(finfo.getFileId());
			 *
			 * 2.采用本机的nginx缓存机制
			 */
			String url = SystemConfig.FILE_SYSTEM_URL + finfo.getFileId();

			/* 判断是否是缩略图，是则重新拼接url */
			String slaveName = downloadReqBean.getSlaveName();
			/* 请求参数中图片处理类型 */
			String fileThmubInDb = finfo.getSlaveName();
			/* 保存在数据库中的缩略图的类型 */

			if (null != slaveName && (!"".equals(slaveName))) {
				/* 是某一个缩略图 */
				if (CommonUtil.isContainsStr(fileThmubInDb, slaveName, ",")) {
					String endwithurl = url.substring(url.lastIndexOf("."));
					url = url.substring(0, url.lastIndexOf(".")) + "_"
							+ slaveName + endwithurl;
					filename = filename.substring(0, filename.lastIndexOf("."))
							+ "_" + slaveName + endwithurl;
				} else {
					responseForClient(response, "文件系统中无相关缩略图", request,
							filename);
					return;
				}
			}
			/* 添加下载次数统计 */
			try {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("fileDownloadCounts", finfo.getFileDownloadCounts() + 1);
				map.put("fsId", finfo.getFsId());
				fdfsInfoServiceImpl.updateFileDownloadCounts(map);
			} catch (Exception e) {
				log.error("更新下载次数出错");
			}
			log.info("下载文件:" + url);
			HttpClientProxy.handleDownload(url, request, response, filename,
					openType);
		} catch (IllegalArgumentException e) {
			responseForClient(response, "附件地址存库错误", request, filename);
			return;
		} catch (ResourceNotFoundException e) {
			responseForClient(response, "附件不存在", request, filename);
			return;
		} catch (IOException e) {
			responseForClient(response, "文件读写异常", request, filename);
			return;
		} catch (Exception e) {
			responseForClient(response, "文件下载出现其他错误，请重新下载", request, filename);
			return;
		}
	}

	/**
	 * <br>
	 * 描 述：插入错误信息到数据库中 <br>
	 * 作 者：checkSun <br>
	 * 历 史: (版本) 作者 时间 注释
	 *
	 * @param errmsg
	 * @param request
	 * @param filename
	 */
	private void addErrLogInfo(String errmsg, HttpServletRequest request,
			String filename) {
		try {

			ErrorInfo errlog = new ErrorInfo(UUID.randomUUID().toString()
					.replaceAll("-", ""), "download", errmsg, new Date(),
					CommonUtil.getIp(request), filename);
			/* 保存数据到数据库 */
			errorInfoService.insert(errlog);

		} catch (Exception e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * <br>
	 * 描 述：保存错误信息并返回客户端错误信息 <br>
	 * 作 者：checkSun <br>
	 * 历 史: (版本) 作者 时间 注释
	 *
	 * @param response
	 * @param errMsg
	 * @param request
	 * @param filename
	 */
	private void responseForClient(HttpServletResponse response, String errMsg,
			HttpServletRequest request, String filename) {
		try {
			log.error(errMsg);
			addErrLogInfo(errMsg, request, filename);
			response.setContentType("text/html;charset=UTF-8");
			response.getWriter().write(errMsg);
			response.getWriter().flush();
			response.getWriter().close();
			return;
		} catch (IOException e) {
			log.error(e.getMessage());
			return;
		} catch (Exception e) {

			log.error(e.getMessage());
			return;
		}

	}

	/**
	 *
	 * <br>
	 * 描 述：根据FileId获取文件名 <br>
	 * 作 者：zj <br>
	 * 历 史: (版本) 作者 时间 注释
	 *
	 * @param fileId
	 * @return
	 */
	public String getFileName(String fileId) {
		String fileName = "";
		int pos = StringUtils.lastIndexOf(fileId, "/");
		if (pos > -1) {
			fileName = StringUtils.substring(fileId, pos);
		}
		return fileName;
	}


}
